---
description:
  Control and customize GraphQL schema built from REST service requests/responses using GraphQL Mesh
  JSON Schema handler. Learn more.
---

import { Callout } from '@theguild/components'

# JSON Schema or Samples

![image](https://user-images.githubusercontent.com/20847995/79218994-11434880-7e5a-11ea-8594-08185526080f.png)

<Callout>
  For a guided tutorial, please refer to ["How to: Configure Sources with no
  definition"](/docs/getting-started/sources-with-no-definition)
</Callout>

This handler allows you to load any remote REST service and describe its request/response using the
YAML config.

You can easily customize and control the built GraphQL schema with this handler.

To get started, install the handler library:

```sh npm2yarn
npm i @graphql-mesh/json-schema
```

Now, you can use it directly in your Mesh config file:

```yaml filename=".meshrc.yaml"
sources:
  - name: MyApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: users
            path: /users
            method: GET
            responseSchema: ./json-schemas/users.json
```

## Headers

[Read about configuration and examples](/docs/guides/headers)

### From Arguments

Mesh automatically generates arguments for operations if needed;

```yaml filename=".meshrc.yaml" {9}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: user
            path: /user/{args.id}
            method: GET
            responseSchema: ./json-schemas/user.json
```

This example operation definition will generate a root field with `id: ID` argument. Mesh will
interpolate the expression in `path` to get `id` value from `args`.

### From JSON Samples

Mesh can also load JSON samples from a remote service. Add a `json-samples` directory in your
project root, and put the JSON samples there
(`responseSample: ./jsons/MyField.response.json{:yaml}` - Create a new folder like `Jsons`). By
declaring the `responseSample`, you can use the JSON sample in the GraphQL schema.

`Mesh Sample Example - .meshrc.yml file`

```yaml filename=".meshrc.yaml" {11}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: MyField
            path: /MyField?id={args.id}
            method: GET
            responseSample: ./jsons/MyField.response.json
            responseTypeName: MyResponseName
            argTypeMap:
              id:
                type: string
```

`Mesh Sample Example - ./jsons/MyField.response.json file`

```json filename="MyField.response.json"
Any JSON sample file can be used.
```

## Query Parameters

There are a few methods to define the query parameters, select the one that fits your needs (Or
combine them):

### Auto declare:

Mesh automatically generates arguments for operations if needed. Note that the arguments are
generated as nullable strings by default.

```yaml filename=".meshrc.yaml" {9}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: user
            path: /user?id={args.id}
            method: GET
            responseSchema: ./json-schemas/user.json
```

### With samples:

You can use the JSON samples to define the query parameters.

In this example we declare `limit` and `offset` properties:

```yaml filename=".meshrc.yaml" {11}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: getUsers
            path: /users
            method: GET
            queryParamsSample: ./jsons/MyField.queryParams.json
            responseSample: ./jsons/MyField.response.json
```

In `./jsons/MyField.queryParams.json`:

```json filename="MyField.queryParams.json"
{
  "limit": 10,
  "offset": 0
}
```

### Manual declare:

You can define the arguments of the operation using the `argTypeMap` config field, according to the
JSON Schema spec.

`type: number` will set the property to `Float` and `type: integer` will set it as Int.

In this example we declare `page` argument as an object with `limit` and `offset` properties:

```yaml
argTypeMap:
  page:
    type: object
    properties:
      limit:
        type: integer
      offset:
        type: integer
```

Array can be defined as `type: array` with `items:` and their own `type:`

```yaml
argTypeMap:
  page:
    type: array
    items:
      limit:
        type: integer
      offset:
        type: integer
```

If you need to use symbols that will cause GraphQL to error like ':' or '[' in the query param name,
you can map an alternative definition. With the below example using `name_like` in the query will
end up being `name:like` as the API call.

```yaml
argTypeMap:
  name_like:
    type: string
queryParamArgMap:
  'name:like': name_like
```

In addition, especially for non-primitive types, the arguments should be added to the path using the
`queryParamArgMap` config field.

Here we add the `page` argument to the query parameters:

```yaml
queryParamArgMap:
  page: page
```

And here is the final config:

```yaml filename=".meshrc.yaml" {13-22}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        operations:
          - type: Query
            field: users
            path: /getUsers
            method: GET
            responseSample: ./jsons/MyField.response.json
            responseTypeName: MyResponseName
            argTypeMap:
              page:
                type: object
                properties:
                  limit:
                    type: integer
                  offset:
                    type: integer
            queryParamArgMap:
              page: page
```

### Global arguments

Query arguments could be defined globally, on handler level, so they are added to all operations.

In this example we declare `limit` parameter with the default value of `10`, and `api_key` with
dynamic value taken from the environment:

```yaml filename=".meshrc.yaml" {10}
sources:
  - name: MyGraphQLApi
    handler:
      jsonSchema:
        endpoint: https://some-service-url/endpoint-path/
        queryParams:
          limit: 10
          api_key: '{env.MY_API_KEY}'
```

<Callout>
  Note that `queryParams` are automatically added to the query. If argument is defined both on
  handler AND operation level, the operation level argument will be used.
</Callout>

## CodeSandBox Example

You can check out our example that uses the JSON Schema handler with mock data.

<iframe
  src="https://codesandbox.io/embed/github/ardatan/graphql-mesh/tree/master/examples/json-schema-example?fontsize=14&hidenavigation=1&theme=dark&module=%2F.meshrc.yml"
  className="mt-6 w-full h-[500px] rounded-md"
  title="json-schema-example"
  allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
  sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
/>

## Config API Reference

import API from '../../../generated-markdown/JsonSchemaHandler.generated.md'

<API />
